package cn.dnui_001zjs.aspect;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;

import org.apache.ibatis.session.SqlSessionFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import org.springframework.web.context.request.RequestContextHolder;

import org.springframework.web.context.request.ServletRequestAttributes;

/**
 *切面类，在此类中编写通知
 */
@Component
public class MyAspect {
	@Autowired
    private SqlSessionFactory sqlSessionFactory;
	// 前置通知
	public void myBefore(JoinPoint joinPoint) {
		System.out.print("AOP目标类是："+joinPoint.getTarget() );
		
		System.out.print("前置通知 ：如执行权限检查...,");
		System.out.println(",被织入增强处理的目标方法为："
                            +joinPoint.getSignature().getName());
	}
	// 后置通知
	public void myAfterReturning(JoinPoint joinPoint) {
		System.out.print("后置通知：如进行日志记录...," );
		System.out.println("被织入增强处理的目标方法为："
                          + joinPoint.getSignature().getName());
	}
	/**
	 * 环绕通知
	 * ProceedingJoinPoint 是JoinPoint子接口，表示可以执行目标方法
	 * 1.必须是Object类型的返回值
	 * 2.必须接收一个参数，类型为ProceedingJoinPoint
	 * 3.必须throws Throwable
	 */
	public Object myAround(ProceedingJoinPoint pjp) 
             throws Throwable {
		// 开始
		System.out.println("环绕开始：执行目标方法之前，如开启事务...");
		// 执行当前目标方法
        // 1.调用目标方法
		long begin = System.nanoTime();

        Object proceed = pjp.proceed();
        long end = System.nanoTime();

        // 2.获取方法
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        String namespace = method.getDeclaringClass().getName();
        String methodName = method.getName();
        // 3.打印SQL语句执行时间
        
        System.out.println("【SQL语句执行时间 "+namespace+"."+methodName+"."+ (end-begin)/1000000+"毫秒】");
        
      
		// 结束
		System.out.println("环绕结束：执行目标方法之后，如关闭事务...");
		// 4.通知同步程序
		return proceed;
	}
	// 异常通知
	public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
		System.out.println("异常通知：" + "出错了" + e.getMessage());
	}
	// 最终通知
	public void myAfter() {
		System.out.println("最终通知：如方法结束后的释放资源...");
	}
}
